2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_PAINTELEMENTGROUP_JUCEHEADER__
27 #define __JUCER_PAINTELEMENTGROUP_JUCEHEADER__
29 #include "jucer_PaintElement.h"
30 #include "../jucer_ObjectTypes.h"
33 //==============================================================================
36 class PaintElementGroup
: public PaintElement
39 //==============================================================================
40 PaintElementGroup (PaintRoutine
* owner
)
41 : PaintElement (owner
, "Group")
45 ~PaintElementGroup() {}
47 //==============================================================================
48 void ungroup (const bool undoable
)
50 getOwner()->getSelectedElements().deselectAll();
51 getOwner()->getSelectedPoints().deselectAll();
53 const int index
= getOwner()->indexOfElement (this);
55 for (int i
= 0; i
< subElements
.size(); ++i
)
57 XmlElement
* const xml
= subElements
.getUnchecked(i
)->createXml();
59 PaintElement
* newOne
= getOwner()->addElementFromXml (*xml
, index
, undoable
);
60 getOwner()->getSelectedElements().addToSelection (newOne
);
65 getOwner()->removeElement (this, undoable
);
68 static void groupSelected (PaintRoutine
* const routine
)
70 if (routine
->getSelectedElements().getNumSelected() > 1)
72 PaintElementGroup
* newGroup
= new PaintElementGroup (routine
);
76 for (int i
= 0; i
< routine
->getNumElements(); ++i
)
78 if (routine
->getSelectedElements().isSelected (routine
->getElement (i
)))
80 XmlElement
* xml
= routine
->getElement(i
)->createXml();
82 PaintElement
* newOne
= ObjectTypes::createElementForXml (xml
, routine
);
84 newGroup
->subElements
.add (newOne
);
93 routine
->deleteSelected();
95 PaintElement
* const g
= routine
->addNewElement (newGroup
, frontIndex
, true);
96 routine
->getSelectedElements().selectOnly (g
);
100 int getNumElements() const throw() { return subElements
.size(); }
102 PaintElement
* getElement (const int index
) const throw() { return subElements
[index
]; }
104 int indexOfElement (const PaintElement
* element
) const throw() { return subElements
.indexOf (element
); }
106 bool containsElement (const PaintElement
* element
) const
108 if (subElements
.contains (element
))
111 for (int i
= subElements
.size(); --i
>= 0;)
113 PaintElementGroup
* pg
= dynamic_cast <PaintElementGroup
*> (subElements
.getUnchecked(i
));
115 if (pg
!= 0 && pg
->containsElement (element
))
122 //==============================================================================
123 void setInitialBounds (int parentWidth
, int parentHeight
)
127 const Rectangle
<int> getCurrentBounds (const Rectangle
<int>& parentArea
) const
131 if (subElements
.size() > 0)
133 r
= subElements
.getUnchecked(0)->getCurrentBounds (parentArea
);
135 for (int i
= 1; i
< subElements
.size(); ++i
)
136 r
= r
.getUnion (subElements
.getUnchecked(i
)->getCurrentBounds (parentArea
));
142 void setCurrentBounds (const Rectangle
<int>& b
, const Rectangle
<int>& parentArea
, const bool undoable
)
144 Rectangle
<int> newBounds (b
);
145 newBounds
.setSize (jmax (1, newBounds
.getWidth()),
146 jmax (1, newBounds
.getHeight()));
148 const Rectangle
<int> current (getCurrentBounds (parentArea
));
150 if (newBounds
!= current
)
152 const int dx
= newBounds
.getX() - current
.getX();
153 const int dy
= newBounds
.getY() - current
.getY();
155 const double scaleStartX
= current
.getX();
156 const double scaleStartY
= current
.getY();
157 const double scaleX
= newBounds
.getWidth() / (double) current
.getWidth();
158 const double scaleY
= newBounds
.getHeight() / (double) current
.getHeight();
160 for (int i
= 0; i
< subElements
.size(); ++i
)
162 PaintElement
* const e
= subElements
.getUnchecked(i
);
164 Rectangle
<int> pos (e
->getCurrentBounds (parentArea
));
166 const int newX
= roundToInt ((pos
.getX() - scaleStartX
) * scaleX
+ scaleStartX
+ dx
);
167 const int newY
= roundToInt ((pos
.getY() - scaleStartY
) * scaleY
+ scaleStartY
+ dy
);
169 pos
.setBounds (newX
, newY
,
170 roundToInt ((pos
.getRight() - scaleStartX
) * scaleX
+ scaleStartX
+ dx
) - newX
,
171 roundToInt ((pos
.getBottom() - scaleStartY
) * scaleY
+ scaleStartY
+ dy
) - newY
);
173 e
->setCurrentBounds (pos
, parentArea
, undoable
);
178 //==============================================================================
179 void draw (Graphics
& g
, const ComponentLayout
* layout
, const Rectangle
<int>& parentArea
)
181 for (int i
= 0; i
< subElements
.size(); ++i
)
182 subElements
.getUnchecked(i
)->draw (g
, layout
, parentArea
);
185 void getEditableProperties (Array
<PropertyComponent
*>& properties
)
187 properties
.add (new UngroupProperty (this));
190 void fillInGeneratedCode (GeneratedCode
& code
, String
& paintMethodCode
)
192 for (int i
= 0; i
< subElements
.size(); ++i
)
193 subElements
.getUnchecked(i
)->fillInGeneratedCode (code
, paintMethodCode
);
196 static const char* getTagName() throw() { return "GROUP"; }
198 XmlElement
* createXml() const
200 XmlElement
* e
= new XmlElement (getTagName());
202 for (int i
= 0; i
< subElements
.size(); ++i
)
204 XmlElement
* const sub
= subElements
.getUnchecked(i
)->createXml();
205 e
->addChildElement (sub
);
211 bool loadFromXml (const XmlElement
& xml
)
213 if (xml
.hasTagName (getTagName()))
215 forEachXmlChildElement (xml
, e
)
217 PaintElement
* const pe
= ObjectTypes::createElementForXml (e
, owner
);
220 subElements
.add (pe
);
233 OwnedArray
<PaintElement
> subElements
;
235 class UngroupProperty
: public ButtonPropertyComponent
238 UngroupProperty (PaintElementGroup
* const element_
)
239 : ButtonPropertyComponent ("ungroup", false),
246 element
->ungroup (true);
249 const String
getButtonText() const
255 PaintElementGroup
* const element
;
260 #endif // __JUCER_PAINTELEMENTGROUP_JUCEHEADER__